<?php
/**
 * Created by PhpStorm.
 * User: worry
 * Date: 2016/12/29
 * Time: 7:54
 */

namespace common\helps;


use Yii;
use yii\base\Object;

class Func extends Object
{
    /**
     * 加密方法
     * @param $pass
     * @return string
     */
    public static function password($pass)
    {
        return strlen($pass) < 20 ? sha1(md5($pass)) : $pass;
    }

    /**
     * 获取时间字符串
     * @param null $time
     * @param int $format_key
     * @return false|string
     */
    public static function getDateStr($time = null, $format_key = 1)
    {
        $format_config = [
            1 => 'Y-m-d H:i:s',
            2 => 'Y-m-d',
            3 => 'Y-m-d H:i',
        ];

        $format = array_key_exists($format_key, $format_config) ? $format_config[$format_key] : $format_config[1];
        if ($time === null) {
            return date($format, time());
        } else {
            return is_int($time) && $time > 0 ? date($format, $time) : '';
        }
    }


    /**
     * 下载
     * @param $file
     * @param string $name
     */
    public static function download($file, $name = '')
    {
        $fileName = $name ? $name : pathinfo($file, PATHINFO_FILENAME);
        $filePath = realpath($file);

        $fp = fopen($filePath, 'rb');

        if (!$filePath || !$fp) {
            header('HTTP/1.1 404 Not Found');
            echo "This file is can't download:file is not exists";
            exit;
        }

        $fileName = $fileName . '.' . pathinfo($filePath, PATHINFO_EXTENSION);
        $encoded_filename = urlencode($fileName);
        $encoded_filename = str_replace("+", "%20", $encoded_filename);

        header('HTTP/1.1 200 OK');
        header("Pragma: public");
        header("Expires: 0");
        header("Content-type: application/octet-stream");
        header("Content-Length: " . filesize($filePath));
        header("Accept-Ranges: bytes");
        header("Accept-Length: " . filesize($filePath));

        $ua = $_SERVER["HTTP_USER_AGENT"];
        if (preg_match("/MSIE/", $ua)) {
            header('Content-Disposition: attachment; filename="' . $encoded_filename . '"');
        } else if (preg_match("/Firefox/", $ua)) {
            header('Content-Disposition: attachment; filename*="utf8\'\'' . $fileName . '"');
        } else {
            header('Content-Disposition: attachment; filename="' . $fileName . '"');
        }

        // ob_end_clean(); <--有些情况可能需要调用此函数
        // 输出文件内容
        fpassthru($fp);
        exit;
    }

    /**
     * 限制字数显示
     * @param $str
     * @param int $start
     * @param $length
     * @param string $charset
     * @param bool $suffix
     * @return string
     */
    public static function moreHidden($str, $start = 0, $length, $charset = "utf-8", $suffix = true)
    {
        //去除HTML标签
        $str = strip_tags(html_entity_decode($str));
        //去除HTML实体
        preg_match_all('/&\w+;/m', $str, $matches);
        $matches = array_unique($matches[0]);
        foreach ($matches as $item) {
            $str = str_replace($item, html_entity_decode($item), $str);
        }

        if (function_exists("mb_substr"))
            $slice = mb_substr($str, $start, $length, $charset);
        else if (function_exists('iconv_substr')) {
            $slice = iconv_substr($str, $start, $length, $charset);
            if (false === $slice) {
                $slice = '';
            }
        } else {
            $re['utf-8'] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/";
            $re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/";
            $re['gbk'] = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
            $re['big5'] = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/";
            preg_match_all($re[$charset], $str, $match);
            $slice = join("", array_slice($match[0], $start, $length));
        }
        $fix = '';
        if (strlen($slice) < strlen($str)) {
            $fix = '...';
        }
        return $suffix ? $slice . $fix : $slice;
    }

    /**
     * 二维数组按键值排序
     * @param $arr
     * @param $key
     * @param bool $asc
     * @return mixed
     */
    public static function sortByKey(&$arr, $key, $asc = true)
    {
        $len = count($arr);
        for ($i = 0; $i < $len; $i++) {
            for ($j = $len - 1; $j > $i; $j--) {
                if ($asc ? $arr[$j][$key] < $arr[$j - 1][$key] : $arr[$j][$key] > $arr[$j - 1][$key]) {
                    $tmp = $arr[$j - 1];
                    $arr[$j - 1] = $arr[$j];
                    $arr[$j] = $tmp;
                }
            }
        }
        return $arr;
    }

    /**
     * curl 提交POST请求
     * @param $gateway_url
     * @param $req_data
     * @param null $optional_headers
     * @param bool $isSSL
     * @return mixed
     */
    public static function http_post($gateway_url, $req_data, $optional_headers = null, $isSSL = false)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $gateway_url);                //配置网关地址
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POST, 1);                          //设置post提交
        curl_setopt($ch, CURLOPT_POSTFIELDS, $req_data);            //post传输数据
        if ($optional_headers !== null) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $optional_headers);
        } else {
            curl_setopt($ch, CURLOPT_HEADER, 0);                        //过滤HTTP头
        }
        if ($isSSL) {
            curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1); //SSL版本
        }
        $data = curl_exec($ch);
        curl_close($ch);
        return $data;
    }

    /**
     * curl GET 请求
     * @param $url
     * @return bool|mixed
     */
    public static function http_get($url)
    {
        $ch = curl_init();
        $timeout = 10;

        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
        if (strpos($url, 'https') == 0) {
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //不验证证书
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); //不验证证书
        }
        $content = curl_exec($ch);
        curl_close($ch);
        if ($content) {
            return $content;
        } else {
            return false;
        }
    }

    /**
     * 删除文件
     * @param string $dir 目录
     * @param string $match 匹配规则
     * @param bool $delDir 是否删除目录
     */
    public static function delFile($dir, $match = '', $delDir = true)
    {
        $dir = realpath($dir);
        $op = opendir($dir);
        $isReg = preg_match('/^\/.*?\/\w*$/', $match) ? true : false;
        while (($file = readdir($op)) !== false) {
            if ($file == '.' || $file == '..') {
                continue;
            }

            $path = $dir . '/' . $file;
            if (is_dir($path)) {
                self::delFile($path, $match, $delDir);
            } else {
                if ($match) {
                    if ($isReg && !preg_match($match, $file)) {
                        continue;
                    }
                    if (!$isReg && strpos($file, $match) === false) {
                        continue;
                    }
                }
                unlink($path);
            }
        }
        closedir($op);
        if ($delDir && !$match) {
            rmdir($dir);
        }
    }

    /**
     * 读取目录下的文件名
     * @param string $dir 目录
     * @param bool $includeDir 结果是否包含目录
     * @param bool|int $level 读取层级 true 为读取所有
     * @return array|bool
     */
    public static function getFileNameByPath($dir, $includeDir = true, $level = true)
    {
        $dir = realpath($dir);
        if (is_dir($dir)) {
            $files = scandir($dir);
            $filesArr = [];
            foreach ($files as $filename) {
                if ($filename == '.' || $filename == '..') {
                    continue;
                }
                $path = $dir . '/' . $filename;
                if (is_dir($path)) {
                    if ($includeDir) {
                        $filesArr[] = $path;
                    }

                } else {
                    $filesArr[] = $path;
                }


                if (
                    ($level === true || (is_int($level) && $level - 1))
                    && is_dir($path)
                    && $subFile = self::getFileNameByPath($path, $includeDir, $level - 1)
                ) {
                    $filesArr = array_merge($filesArr, $subFile);
                }
            }
            return $filesArr;
        } else {
            return false;
        }
    }

    /**
     * 查询IP归属地
     * @param string $ip
     * @return string
     */
    public static function getIpLocation($ip = '')
    {
        if (empty($ip)) {
            $ip = $_SERVER['REMOTE_ADDR'];
        }
        $res = @file_get_contents('http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=js&ip=' . $ip);
        if (empty($res)) {
            return '--';
        }
        $jsonMatches = [];
        preg_match('#\{.+?\}#', $res, $jsonMatches);
        if (!isset($jsonMatches[0])) {
            return '--';
        }
        $json = json_decode($jsonMatches[0], true);
        if (isset($json['ret']) && $json['ret'] == 1) {
            $json['ip'] = $ip;
            unset($json['ret']);
        } else {
            return '--';
        }
        $jsonInfo = $json['province'] . ' ' . $json['city'];

        return $jsonInfo;
    }

    /**
     * 字符串下划线分割转为驼峰
     * @param $str
     * @param bool $ucFirst
     * @param string $delimiter
     * @return mixed|string
     */
    public static function convertUnderline($str, $ucFirst = true, $delimiter = '_')
    {
        $res = '';
        $strArr = explode($delimiter, $str);
        foreach ($strArr as $key => $item) {
            if ($key == 0 && !$ucFirst) {
                $res .= $item;
                continue;
            }
            $res .= ucfirst($item);
        }
        return $res;
    }

    /**
     * 驼峰转为下划线分割
     * @param $str
     * @param bool $ucFirst
     * @return string
     */
    public static function humpToUnderLine($str, $ucFirst = false)
    {
        $str = trim(preg_replace_callback('/([A-Z])/', function ($matches) {
            return '_' . strtolower($matches[0]);
        }, $str), '_');
        return $str;
    }

    /**
     * 获取当前全域名 eg. http://www.baidu.com:80
     * @return string
     */
    public static function getServerNameByFull()
    {
        return (empty($_SERVER['HTTP_X_CLIENT_PROTO']) ? 'http' : $_SERVER['HTTP_X_CLIENT_PROTO'] . '') . '://' . $_SERVER['HTTP_HOST'] . ':' . $_SERVER['SERVER_PORT'];
    }

    /**
     * 创建目录
     * @param $dir
     * @param int $mode
     * @return bool
     */
    public static function mkdir($dir, $mode = 0755)
    {
        if (!is_dir(dirname($dir))) {
            if (!self::mkdir(dirname($dir), $mode)) {
                return false;
            }
        }
        if (!is_writable(dirname($dir))) {
            return false;
        }
        if (mkdir($dir, $mode)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 获取路径
     * @param string $dirStr
     * @param string $baseDir
     * @return string
     */
    public static function getPath($dirStr, $baseDir)
    {
        preg_match_all('/\{.*?\}/', $dirStr, $matches);

        //替换日期事件
        $t = time();
        $d = explode('-', date("Y-y-m-d-H-i-s"));
        $format = $dirStr;
        $format = str_replace("{yyyy}", $d[0], $format);
        $format = str_replace("{yy}", $d[1], $format);
        $format = str_replace("{mm}", $d[2], $format);
        $format = str_replace("{dd}", $d[3], $format);
        $format = str_replace("{hh}", $d[4], $format);
        $format = str_replace("{ii}", $d[5], $format);
        $format = str_replace("{ss}", $d[6], $format);
        $format = str_replace("{time}", $t, $format);

        //替换随机字符串
        $randNum = rand(1, 10000000000) . rand(1, 10000000000);
        if (preg_match("/\{rand\:([\d]*)\}/i", $format, $matches)) {
            $format = preg_replace("/\{rand\:[\d]*\}/i", substr($randNum, 0, $matches[1]), $format);
        }

        return $baseDir . $format;
    }

    /**
     * 列出目录下的文件（不包含目录）
     * @param string $dir 目录
     * @param array $ext 后缀
     * @param int $max 最大数默认不限制
     * @param int $start 开始记录的位置
     * @param int $offset 记录位置的变量
     * @param array $list 要合并的数组
     * @param int $total 记录总记录数的变量
     * @param bool $isRecord 是否记录的变量
     * @return array|bool
     */
    public static function listFile($dir, $ext = [], $max = 0, $start = 0, $offset = 0, $list = [], $total = 0, $isRecord = true)
    {
        $path = $dir;
        if (!is_dir($path)) {
            return false;
        }
        while ($path[strlen($path) - 1] == '\\' || $path[strlen($path) - 1] == '/') {
            $path = substr($path, 0, strlen($path) - 1);
        }
        $files = glob($path . '/*');
        $ext = array_map('strtolower', $ext);
        foreach ($files as $item) {

            if (is_dir($item)) {
                list($list, $total, $offset) = self::listFile($item, $ext, $max, $start, $offset, $list, $total, $isRecord);
                continue;
            }

            if (!$ext || in_array(strtolower(pathinfo($item, PATHINFO_EXTENSION)), $ext)) {
                if (($max == 0 || ($max != 0 && count($list) < $max)) && $start <= $offset && $isRecord) {
                    $list[] = $item;
                }
                if (count($list) >= $max) {
                    $isRecord = false;
                }
                $offset++;
                $total++;
            }
        }
        return [$list, $total, $offset];
    }

    /**
     * 通用正则验证
     * @param $string
     * @param $pattern
     * @return bool
     */
    public static function validateByRegex($string, $pattern)
    {
        if (preg_match($pattern, $string)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 手机验证
     * @param $string
     * @return bool
     */
    public static function validateMobile($string)
    {
        $pattern = '/^1[34578]\d{9}$/';
        return self::validateByRegex($string, $pattern);
    }

    /**
     * 验证邮箱
     * @param $string
     * @return bool
     */
    public static function validateEmail($string)
    {
        $pattern = '/^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-])+/';
        return self::validateByRegex($string, $pattern);
    }

    /**
     * 验证重复密码
     * @param $pass
     * @param $repass
     * @return bool
     */
    public static function validatePassword($pass, $repass)
    {
        if (!$pass) {
            return false;
        }
        if ($pass != $repass) {
            return false;
        }
        return true;
    }

    /**
     * 获取客户端操作系统
     * @return bool|string
     */
    public static function getClientSystem()
    {
        if (!isset($_SERVER['HTTP_USER_AGENT'])) {
            return false;
        }
        $agent = $_SERVER['HTTP_USER_AGENT'];

        $systemArr = [
            'win', 'win 9x', 'linux', 'unix', 'sun', 'ibm', 'Mac', 'PowerPC', 'AIX', 'HPUX',
            'NetBSD', 'BSD', 'OSF1', 'IRIX', 'FreeBSD', 'teleport', 'flashget', 'webzip', 'offline'
        ];
        $winArr = [
            '95' => '95',
            '4.0' => 'ME',
            '98' => '98',
            'nt 6.0' => 'Vista',
            'nt 6.1' => '7',
            'nt 6.2' => '8',
            'nt 10.0' => '10',
            'nt 5.1' => 'XP',
            'nt 5' => '2000',
            '32' => '32',
        ];
        foreach ($systemArr as $item) {
            if (preg_match('/' . $item . '/i', $agent)) {
                $system = $item;
                if ($item == 'win') {
                    foreach ($winArr as $key => $value) {
                        if (preg_match('/' . $key . '/i', $agent)) {
                            $system .= ' ' . $value;
                            break;
                        }
                    }
                }
                break;
            }
        }
        return $system ?: 'else unknown';
    }

    /**
     * 合并并过滤相同的数组
     * @param $tmp
     * @return array
     */
    public static function filterArray($tmp)
    {
        $args = func_get_args();
        $result = [];
        foreach ($args as $arg) {
            foreach ($arg as $item) {
                if(!in_array($item, $result)) {
                    $result[] = $item;
                }
            }
        }
        return $result;
    }
}
